package com.fdb.efp.nls.service.impl.signature;

import com.alibaba.fastjson.JSONObject;
import com.fdb.efp.nls.service.domain.NlsApplyInfo;
import com.fdb.efp.nls.service.domain.signature.SignatureConfiguration;
import com.fdb.efp.nls.service.domain.signature.SignatureRecord;
import com.fdb.efp.nls.service.domain.signature.SignatureStamUploadRecord;
import com.fdb.efp.nls.service.domain.sx.NlsCreditInfo;
import com.fdb.efp.nls.service.facade.signature.SignatureService;
import com.fdb.efp.nls.service.vo.signature.SignatureRecordVO;
import com.fdb.efp.nls.service.vo.signature.SignatureStamUploadRecordVO;
import com.fdb.basic.framework.core.base.FrameworkService;
import com.fdb.basic.framework.core.exception.BizException;
import com.fdb.basic.framework.core.exception.ESBException;
import com.fdb.basic.framework.core.exception.OcmSystemException;
import com.fdb.basic.framework.core.util.*;
import com.fdb.efp.nls.common.psd.PsdConstantSet;
import com.fdb.efp.nls.service.facade.SCfgParamService;
import com.fdb.efp.console.service.vo.SCfgParamVO;
import com.fdb.efp.cus.service.facade.CusIndivService;
import com.fdb.efp.cus.service.vo.CusIndivVO;
import com.fdb.efp.nls.service.vo.CfcaSignInfoVO;
import com.fdb.efp.nls.service.facade.CfcaSignInfoService;
import com.fdb.efp.esb.common.constant.ElectronicSignatureConstant;
import com.fdb.efp.esb.common.constant.ElectronicSignatureEnums;
import com.fdb.efp.esb.service.bo.req.dzqz.ReqElectronicSignature3203Bean;
import com.fdb.efp.esb.service.bo.req.dzqz.ReqElectronicSignatureDL01Bean;
import com.fdb.efp.esb.service.bo.req.dzqz.info.*;
import com.fdb.efp.esb.service.bo.req.sed.cfca.ReqSedCfcaOpenAccountBean;
import com.fdb.efp.esb.service.bo.resp.dzqz.RspElectronicSignature3203Bean;
import com.fdb.efp.esb.service.bo.resp.dzqz.RspElectronicSignatureDL01Bean;
import com.fdb.efp.esb.service.bo.resp.dzqz.info.ElectronicSignature3203Signatory;
import com.fdb.efp.esb.service.bo.resp.dzqz.info.RspElectronicSignature3203BaseBean;
import com.fdb.efp.esb.service.bo.resp.sed.cfca.RespSedCfcaOpenAccountBean;
import com.fdb.efp.esb.service.facade.sed.cfca.SedCfcaService;
import com.fdb.efp.nls.service.dao.NlsApplyInfoDao;
import com.fdb.efp.nls.service.dao.signature.SignatureConfigurationDAO;
import com.fdb.efp.nls.service.dao.signature.SignatureRecordDAO;
import com.fdb.efp.nls.service.dao.signature.SignatureStamUploadRecordDAO;
import com.fdb.efp.nls.service.dao.sx.NlsCreditInfoDao;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 协议文件签章服务类
 *
 * @author xiaojunhui<br />
 */
@Service("signatureService")
public class SignatureServiceImpl implements SignatureService, FrameworkService {

    private static Logger logger = LoggerFactory.getLogger(SignatureServiceImpl.class);

    @Autowired
    private SignatureConfigurationDAO signatureConfigurationDAO;

    @Autowired
    private SignatureRecordDAO signatureRecordDAO;

    @Autowired
    private NlsCreditInfoDao nlsCreditInfoDao;

    @Autowired
    private NlsApplyInfoDao nlsApplyInfoDao;

    @Autowired
    @Qualifier("cusIndivService")
    private CusIndivService cusIndivService;

    @Autowired
    @Qualifier("sedCfcaService")
    private SedCfcaService sedCfcaService;

    @Autowired
    @Qualifier("cfcaSignInfoService")
    private CfcaSignInfoService cfcaSignInfoService;

    @Autowired
    private SignatureStamUploadRecordDAO signatureStamUploadRecordDAO;

    @Autowired
    private SCfgParamService sCfgParamService;

    @Value("${gzcb.authaddr}")
    private String authaddr;

    public static ArrayList<String> prdIds;

    static {
        prdIds = new ArrayList<>();
        prdIds.add(PsdConstantSet.prdId);
    }

    @Override
    public Boolean signature() {
        logger.info("开始进行在线签章");
        //根据配置的产品取获取签章配置信息
        for (String prdId : prdIds) {
            List<SignatureConfiguration> configurations = signatureConfigurationDAO.selectByPrdId(prdId);
            if (configurations == null || configurations.isEmpty()) {
                logger.info("产品：", prdId, "获取到的配置数据为空");
                continue;
            }
            //获取配置的处理数量以及重试次数
            final int[] handleNumArr = getHandleNumArr();
            for (SignatureConfiguration configuration : configurations) {
                //一个个配置的处理 每个配置获取相同数据的记录进行处理
                if (configuration.getLinkType() == 1) {
                    List<NlsCreditInfo> signatureNlsList = nlsCreditInfoDao.getSignatureNlsList(prdId, handleNumArr[1], configuration.getPolFileType(), handleNumArr[0]);
                    if (signatureNlsList == null || signatureNlsList.isEmpty()) {
                        logger.info("获取到需要处理的数据为空");
                        continue;
                    }
                    List<NlsSignatureInfo> nlsSignatureInfos = signatureNlsList
                            .stream().map(nlsCreditInfo -> {
                                NlsSignatureInfo nlsSignatureInfo = new NlsSignatureInfo();
                                nlsSignatureInfo.setUsrNm(nlsCreditInfo.getCusName());
                                nlsSignatureInfo.setCertTp(nlsCreditInfo.getCertType());
                                nlsSignatureInfo.setCertNo(nlsCreditInfo.getCertCode());
                                nlsSignatureInfo.setUserEmail(nlsCreditInfo.getEmail());
                                nlsSignatureInfo.setMblNo(nlsCreditInfo.getIndivMobile());
                                nlsSignatureInfo.setCtcAddr(nlsCreditInfo.getIndivRsdAddr());
                                nlsSignatureInfo.setApplySeq(nlsCreditInfo.getLmtApplySeq());
                                nlsSignatureInfo.setCusId(nlsCreditInfo.getCusId());
                                return nlsSignatureInfo;
                            })
                            .collect(Collectors.toList());
                    signature1(configuration, nlsSignatureInfos);
                }
                if (configuration.getLinkType() == 2) {
                    List<NlsApplyInfo> signatureNlsList = nlsApplyInfoDao.getSignatureNlsList(prdId, handleNumArr[1], configuration.getPolFileType(), handleNumArr[0]);
                    if (signatureNlsList == null || signatureNlsList.isEmpty()) {
                        logger.info("获取到需要处理的数据为空");
                        continue;
                    }
                    List<NlsSignatureInfo> nlsSignatureInfos = signatureNlsList
                            .stream().map(nlsApplyInfo -> {
                                NlsSignatureInfo nlsSignatureInfo = new NlsSignatureInfo();
                                nlsSignatureInfo.setUsrNm(nlsApplyInfo.getCusName());
                                nlsSignatureInfo.setCertTp(nlsApplyInfo.getCertType());
                                nlsSignatureInfo.setCertNo(nlsApplyInfo.getCertCode());
                                nlsSignatureInfo.setUserEmail("");
                                nlsSignatureInfo.setMblNo(nlsApplyInfo.getMblTelNo());
                                nlsSignatureInfo.setCtcAddr(nlsApplyInfo.getIndivRsdAddr());
                                nlsSignatureInfo.setApplySeq(nlsApplyInfo.getApplySeq());
                                nlsSignatureInfo.setCusId(nlsApplyInfo.getCusId());
                                return nlsSignatureInfo;
                            }).collect(Collectors.toList());
                    signature1(configuration, nlsSignatureInfos);
                }
            }
        }
        return Boolean.TRUE;
    }

    /**
     * 签章处理
     *
     * @param configuration
     * @param nlsSignatureInfos
     */
    private final void signature1(SignatureConfiguration configuration, List<NlsSignatureInfo> nlsSignatureInfos) {
        if (nlsSignatureInfos == null) {
            return;
        }
        if (nlsSignatureInfos.isEmpty()) {
            return;
        }
        //遍历集合一条条记录进行处理
        for (NlsSignatureInfo nlsSignatureInfo : nlsSignatureInfos) {
            //插入一条日志记录到签章记录表 状态为0 初始化状态 1 成功 2 失败 3 签章成功，下载文件失败
            //如果数据库已经存在记录，那么进行更新
            SignatureRecord sigRecord = getSignatureRecord(configuration, nlsSignatureInfo.getApplySeq());
            if (sigRecord.getSiuSta() == 3) {
                //签章成功 但是下载失败的 代表本地不存在签章合同
                //走下载动作 成功下载到本地 才算成功
                final RspElectronicSignature3203BaseBean rspElectronicSignature3203BaseBean = JSONObject.parseObject(sigRecord.getSiuRetMsg(), RspElectronicSignature3203BaseBean.class);
                boolean downFlag = executeDL01(rspElectronicSignature3203BaseBean.getContrNo(), sigRecord, configuration, nlsSignatureInfo.getApplySeq());
                if (!downFlag) {
                    logger.info("下载失败", nlsSignatureInfo.getApplySeq(), rspElectronicSignature3203BaseBean.getContrNo());
                    sigRecord.setLastUpdateTime(new Date());
                    signatureRecordDAO.updateByPrimaryKey(sigRecord);
                    continue;
                }
                //插入一条记录到加戳表
                insertStamUp(configuration, nlsSignatureInfo, sigRecord);
                //下载成功 那么设置成功
                sigRecord.setSiuSta(1);
                sigRecord.setLastUpdateTime(new Date());
                signatureRecordDAO.updateByPrimaryKey(sigRecord);
                continue;
            }
            //签章以及下载
            try {
                //获取客户信息
                CusIndivVO cusIndiv = getCusIndiv(nlsSignatureInfo.getCusId());
                if (cusIndiv == null) {
                    throw new RuntimeException("获取不到客户信息");
                }
                String axqUsrId = cusIndiv.getAxqUsrId();
                if (StringUtils.isEmpty(nlsSignatureInfo.getUserEmail())) {
                    nlsSignatureInfo.setUserEmail(cusIndiv.getEmail());
                }
                if (StringUtils.isEmpty(axqUsrId)) {
                    //需要调用接口去开户
                    RespSedCfcaOpenAccountBean respAccountBean = execute3001(nlsSignatureInfo);
                    if (respAccountBean == null || StringUtils.isEmpty(respAccountBean.getPerson().getUsrID())) {
                        throw new RuntimeException("调用安心签开户失败（或者获取到的安心签客户号为空）");
                    }
                    //开户成功 那么更新回到客户表
                    updateCusIndiv(cusIndiv, respAccountBean);
                    axqUsrId = respAccountBean.getPerson().getUsrID();
                }
                //拿到安心签客户号，那么继续往下走签章方法
                RspElectronicSignature3203BaseBean resp3203BaseBean = execute3203(configuration, axqUsrId, nlsSignatureInfo.getApplySeq(), configuration.getPrdId(), configuration.getPrdCode(), configuration.getPrdName(), cusIndiv.getCusId(), cusIndiv.getCusName());
                if (resp3203BaseBean == null) {
                    throw new RuntimeException("调用签章接口失败，返回的信息为空");
                }
                sigRecord.setSiuSta(1);
                sigRecord.setLastUpdateTime(new Date());
                sigRecord.setSiuRetMsg(JSONObject.toJSONString(resp3203BaseBean));
                signatureRecordDAO.updateByPrimaryKey(sigRecord);
                //下载文件
                boolean downFlag = executeDL01(resp3203BaseBean.getContrNo(), sigRecord, configuration, nlsSignatureInfo.getApplySeq());
                if (!downFlag) {
                    sigRecord.setSiuSta(3);
                    signatureRecordDAO.updateByPrimaryKey(sigRecord);
                    continue;
                }
                //都完成 那么设置为成功
                sigRecord.setSiuSta(1);
                sigRecord.setLastUpdateTime(new Date());
                signatureRecordDAO.updateByPrimaryKey(sigRecord);
                //插入一条记录到加戳表
                insertStamUp(configuration, nlsSignatureInfo, sigRecord);
                continue;
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("发生异常", e);
                //修改状态
                sigRecord.setSiuSta(2);
                sigRecord.setErrMsg("发生异常:" + e.getLocalizedMessage());
                signatureRecordDAO.updateByPrimaryKey(sigRecord);
                //跳到下一个进行处理
                continue;
            }
        }
    }

    /**
     * 插入记录到签章表
     *
     * @param configuration
     * @param nlsSignatureInfo
     * @param sigRecord
     */
    private void insertStamUp(SignatureConfiguration configuration, NlsSignatureInfo nlsSignatureInfo, SignatureRecord sigRecord) {
        //先查询是否已经存在相同的记录了
        String fileUrl = configuration.getSiuFileSaveDir() + nlsSignatureInfo.getApplySeq() + "/" + configuration.getPolFileType() + "." + FilenameUtils.getExtension(configuration.getPolFileUrl());
        if (signatureStamUploadRecordDAO.selectBySiuFileUrl(fileUrl) > 0) {
            return;
        }
        SignatureStamUploadRecord stamUploadRecord = new SignatureStamUploadRecord();
        stamUploadRecord.setHdlNum(0);
        stamUploadRecord.setHdlSta(0);
        stamUploadRecord.setCreateTime(new Date());
        stamUploadRecord.setId(UUIDUtil.getUUID());
        stamUploadRecord.setSignatureRecordId(sigRecord.getId());
        stamUploadRecord.setSiuFileUrl(fileUrl);
        signatureStamUploadRecordDAO.insert(stamUploadRecord);
    }

    /**
     * 获取签章记录信息
     *
     * @param configuration 配置信息
     * @param applySeq      申请流水号
     * @return
     */
    private SignatureRecord getSignatureRecord(SignatureConfiguration configuration, String applySeq) {
        //先从数据库获取
        SignatureRecord signatureRecord = signatureRecordDAO.selectByPst(configuration.getPrdId(), applySeq, configuration.getLinkType());
        if (signatureRecord == null) {
            SignatureRecord sigRecord = new SignatureRecord();
            sigRecord.setApplySeq(applySeq);
            sigRecord.setCreateTime(new Date());
            sigRecord.setId(UUIDUtil.getUUID());
            sigRecord.setLinkType(configuration.getLinkType());
            sigRecord.setPolFileType(configuration.getPolFileType());
            sigRecord.setPrdId(configuration.getPrdId());
            sigRecord.setRetryNum(1);
            sigRecord.setSiuSta(0);
            signatureRecordDAO.insert(sigRecord);
            return sigRecord;
        }
        signatureRecord.setRetryNum(signatureRecord.getRetryNum() + 1);
        signatureRecord.setLastUpdateTime(new Date());
        signatureRecordDAO.updateByPrimaryKey(signatureRecord);
        return signatureRecord;
    }

    /**
     * 更新客户信息
     *
     * @param cusIndiv
     * @param respAccountBean
     */
    private Integer updateCusIndiv(CusIndivVO cusIndiv, RespSedCfcaOpenAccountBean respAccountBean) {
        cusIndiv.setAxqUsrId(respAccountBean.getPerson().getUsrID());
        return cusIndivService.updateByPk(cusIndiv);
    }

    /**
     * 根据客户号获取客户信息
     *
     * @param cusId
     * @return
     */
    private CusIndivVO getCusIndiv(String cusId) {
        CusIndivVO cusIndivVO = new CusIndivVO();
        cusIndivVO.setCusId(cusId);
        CusIndivVO targetCusIndivVo = cusIndivService.queryByPk(cusIndivVO);
        return targetCusIndivVo;
    }

    /**
     * 调用互金安心签接口
     *
     * @param configuration
     * @param axqUserId
     * @return
     * @throws Exception
     */
    private RspElectronicSignature3203BaseBean execute3203(SignatureConfiguration configuration, String axqUserId, String applySeq, String prdId, String prdCode, String prdName, String cusId, String cusName) throws Exception {
        ReqElectronicSignature3203Bean req3203Bean = new ReqElectronicSignature3203Bean();
        // 组装合同模板签章接口请求包信息，包括[1]、[2]、[3]、[4]、[5]、[6]、[7]
        ElectronicSignature3203BaseInfo req3203BeanBase = new ElectronicSignature3203BaseInfo();
        //[1]：是否签署，0：抄送；1：签署；2：暂不签署；默认为0
        req3203BeanBase.setSignFlg(ElectronicSignatureConstant.IS_SIGN_2);
        //[2]：印章ID = 客户开户号（安心签开户号）
        req3203BeanBase.setSealId(axqUserId);
        //[3]：合同类型
        req3203BeanBase.setContrTp(ElectronicSignatureConstant.CONTRACT_TYPE_CODE_QT);
        //[4]：合同名称
        req3203BeanBase.setContrNm(configuration.getPolFileName());
        //[5]： 关键字签章信息组装 start----------------------------------------------------------
        ElectronicSignature3203SignKeyWord signKeyword = new ElectronicSignature3203SignKeyWord();
        //关键字 = 银行签章
        signKeyword.setSignKwd(configuration.getSiuKeyWord());
        //X轴偏移坐标
        signKeyword.setXOfstCoordPosn(String.valueOf(configuration.getSiuOffsetX()));
        //Y轴偏移坐标
        signKeyword.setYOfstCoordPosn(String.valueOf(configuration.getLinkType()));
        //签章图片宽度
        signKeyword.setSignImgWdth(String.valueOf(configuration.getSiuImgW()));
        //签章图片高度
        signKeyword.setSignImgHght(String.valueOf(configuration.getSiuImgH()));
        //[5]： 关键字签章信息组装 ---------------------------------------------------------- end
        req3203BeanBase.setSignKeyword(signKeyword);
        //[7]：签署信息组装 start------------------------------------------------------------------------
        List<ElectronicSignature3203SignInfo> signInfos = new ArrayList<ElectronicSignature3203SignInfo>();
        ElectronicSignature3203SignInfo signInfo1 = new ElectronicSignature3203SignInfo();
        //用户ID = 安心签开户号  @modify @date 2019/06/10
        signInfo1.setUsrID(axqUserId);
        //授权时间
        signInfo1.setAuthTm(TimeUtil.getTimeStampByPattern("yyyyMMddHHmmss"));
        //授权地址
        signInfo1.setAuthAddr(authaddr);
        //项目编号
        signInfo1.setPrjNo(configuration.getPrdId());
        //按关键字创建签名  @modify @date 2019/06/10
        ElectronicSignature3203SignKeyWord2 signKeyWord2 = new ElectronicSignature3203SignKeyWord2();
        //关键字 = 客户签章
        signKeyWord2.setSignKwd(configuration.getSiuKeyWord());
        signKeyWord2.setXOfstCoordPosn(String.valueOf(configuration.getSiuOffsetX()));
        signKeyWord2.setYOfstCoordPosn(String.valueOf(configuration.getLinkType()));
        signKeyWord2.setSignImgHght(String.valueOf(configuration.getSiuImgH()));
        signKeyWord2.setSignImgWdth(String.valueOf(configuration.getSiuImgW()));
        signInfo1.setSignKeyword2(signKeyWord2);
        //是否代签 1 代签
        signInfo1.setAgncSignFlg("1");
        signInfos.add(signInfo1);
        //[7]：签署信息组装 ------------------------------------------------------------------------ end
        req3203BeanBase.setSignBscInfArry(signInfos);
        // 获取合同流
        req3203Bean.setContrFlStrm(Base64.encodeBytes(FileUtil.toByteArray(new File(configuration.getPolFileUrl()))));
        req3203Bean.setUploadContract(req3203BeanBase);
        RspElectronicSignature3203BaseBean resp3203BaseBean = new RspElectronicSignature3203BaseBean();
        try {
            RspElectronicSignature3203Bean resp3203Bean = sedCfcaService.signContract(req3203Bean);
            resp3203BaseBean = resp3203Bean.getContract();
            if (Objects.isNull(resp3203BaseBean)) {
                throw new Exception("调用cfca合同模板签章接口【3203】，返回的合同签署信息为空！----------授信申请流水号：");
            }
            ElectronicSignature3203Signatory respSignature3203Signatory = resp3203BaseBean.getContractSignInfArry().get(0);
            if (Objects.isNull(respSignature3203Signatory)) {
                throw new Exception("调用cfca合同模板签章接口【3203】，返回的签署人信息为空！----------授信申请流水号：");
            }
        } catch (Exception e) {
            throw e;
        }
        // 保存合同签章记录数据
        this.insertCfcaSignInfo(resp3203BaseBean, applySeq, prdId, prdCode, prdName, cusId, cusName);
        return resp3203BaseBean;
    }

    /**
     * 插入签章信息表
     *
     * @param resp3203BaseBean
     * @param applySeq
     * @param prdId
     * @param prdCode
     * @param prdName
     * @param cusId
     * @param cusName
     * @throws OcmSystemException
     */
    private void insertCfcaSignInfo(RspElectronicSignature3203BaseBean resp3203BaseBean, String applySeq, String prdId, String prdCode, String prdName, String cusId, String cusName) {
        CfcaSignInfoVO cfcaSignInfoVO = new CfcaSignInfoVO();
        //申请流水号
        cfcaSignInfoVO.setApplySeq(applySeq);
        //产品id
        cfcaSignInfoVO.setPrdId(prdId);
        //产品代码
        cfcaSignInfoVO.setPrdCode(prdCode);
        //产品名称
        cfcaSignInfoVO.setPrdName(prdName);
        //合同号
        cfcaSignInfoVO.setContNo(resp3203BaseBean.getContrNo());
        //安心签合同号
        cfcaSignInfoVO.setCfcaContNo(resp3203BaseBean.getContrNo());
        //客户号
        cfcaSignInfoVO.setCusId(cusId);
        //客户名称
        cfcaSignInfoVO.setCusName(cusName);
        //cfca签署状态 = “未签署”
        cfcaSignInfoVO.setCfcaSignState(ElectronicSignatureEnums.CfcaSignmentStateEnum.UNSIGN.getEnname());
        String time = "";
        for (ElectronicSignature3203Signatory elS3203Signatory : resp3203BaseBean.getContractSignInfArry()) {
            if (ElectronicSignatureConstant.SIGN_STATUS_1.equals(elS3203Signatory.getSignSt())) {
                //cfca签署时间
                try {
                    time = DateUtility.formatDateTime14To19(elS3203Signatory.getSignTm());
                } catch (BizException e) {
                    logger.error("时间【" + elS3203Signatory.getSignTm() + "】，不是14位格式的，不符合接口约定，签署时间取本系统时间。");
                    time = TimeUtil.getCurrentDateTime();
                }
            }
        }
        cfcaSignInfoVO.setCfcaSignTime(time);
        cfcaSignInfoService.insertCfcaSignInfo(cfcaSignInfoVO);
    }

    /**
     * @param nlsSignatureInfo
     * @return
     * @throws ESBException
     */
    private RespSedCfcaOpenAccountBean execute3001(NlsSignatureInfo nlsSignatureInfo) throws ESBException {
        ReqSedCfcaOpenAccountBean req3001Bean = new ReqSedCfcaOpenAccountBean();
        //组装个人信息------------------start
        ElectronicSignature3001ReqPersonInfo personInfo = new ElectronicSignature3001ReqPersonInfo();
        //用户名 = 客户名称
        personInfo.setUsrNm(nlsSignatureInfo.getUsrNm());
        //证件类型
        personInfo.setCertTp(nlsSignatureInfo.getCertTp());
        //证件号码（安心签会校验身份证格式）
        personInfo.setCertNo(nlsSignatureInfo.getCertNo());
        //用户邮箱（安心签会校验邮箱格式）
        personInfo.setUserEmail(nlsSignatureInfo.getUserEmail());
        //手机号码（安心签会校验手机号格式）
        personInfo.setMblNo(nlsSignatureInfo.getMblNo());
        //联系地址
        personInfo.setCtcAddr(nlsSignatureInfo.getCtcAddr());
        //认证方式   = “公安部数据联网核查”
        //personInfo.setAuthMode(ElectronicSignatureConstant.AUTHENTICATION_MODE_02);
        personInfo.setAuthMode("公安部");
        //组装个人信息------------------end
        //个人信息
        req3001Bean.setPerson(personInfo);
        //是否发送密码短信，0：发送；1：不发送；默认为0，建议选择发送
        req3001Bean.setSendPswdMsgFlg(ElectronicSignatureEnums.SendEnum.NotSend.VALUE);
        //银行卡号信息（银行已在cfca开过户）
        RespSedCfcaOpenAccountBean resp3001Bean = sedCfcaService.openAccount(req3001Bean);
        return resp3001Bean;
    }


    /**
     * 下载
     *
     * @param cfcaContNo    合同号
     * @param sigRecord
     * @param configuration 配置信息
     * @param applySeq      申请流水号
     */
    private boolean executeDL01(String cfcaContNo, SignatureRecord sigRecord, SignatureConfiguration configuration, String applySeq) {
        ReqElectronicSignatureDL01Bean reqDL01Bean = new ReqElectronicSignatureDL01Bean();
        //安心签合同号
        reqDL01Bean.setContrNo(cfcaContNo);
        try {
            RspElectronicSignatureDL01Bean respDL01Bean = sedCfcaService.downloadContract(reqDL01Bean);
            if (respDL01Bean == null || StringUtils.isEmpty(respDL01Bean.getContrFlStrm())) {
                return false;
            }
            sigRecord.setDwnRetMsg(JSONObject.toJSONString(reqDL01Bean));
            logger.info("合同号：", cfcaContNo, " 返回报文为：", reqDL01Bean != null ? JSONObject.toJSONString(respDL01Bean) : "", " 申请流水号：", applySeq);
            File file = new File(configuration.getSiuFileSaveDir() + applySeq);
            if (!file.exists()) {
                logger.info("合同下载，创建文件路径：",configuration.getSiuFileSaveDir()+applySeq);
                FileUtils.forceMkdir(file);
            }
            logger.info("合同下载，存放下载文件的路径：",configuration.getSiuFileSaveDir()+applySeq);
            logger.info("合同下载成功，返回的文件字符串为：",respDL01Bean.getContrFlStrm());
            // 下载合同到本地指定目录下
            FileUtil.writeBytesToFile(
                    Base64.decode(respDL01Bean.getContrFlStrm()),
                    configuration.getSiuFileSaveDir()
                            + applySeq + "/", configuration.getPolFileType()
                            + "." + FilenameUtils.getExtension(configuration.getPolFileUrl()));
        } catch (Exception e) {
            logger.error("下载合同发生异常", e);
            return false;
        }
        return true;
    }


    @Override
    public SignatureRecordVO selectByPrimaryKey(String id) {

        SignatureRecord signatureRecord = signatureRecordDAO.selectByPrimaryKey(id);

        if (Objects.isNull(signatureRecord)) {
            return null;
        }
        return beanCopy(signatureRecord, new SignatureRecordVO());
    }

    @Override
    public Integer updateRecordByPrimaryKey(SignatureRecordVO signatureRecordVO) {
        if (Objects.isNull(signatureRecordVO)) {
            return 0;
        }
        SignatureRecord signatureRecord = new SignatureRecord();
        beanCopy(signatureRecordVO, signatureRecord);
        return signatureRecordDAO.updateByPrimaryKey(signatureRecord);
    }

    @Override
    public ArrayList<SignatureStamUploadRecordVO> selectStamRecord(Integer maxNum, Integer maxRtyNum) {
        ArrayList<SignatureStamUploadRecordVO> resultStamRecords = new ArrayList<>();
        List<SignatureStamUploadRecord> signatureStamUploadRecords = signatureStamUploadRecordDAO.selectStamRecord(maxNum, maxRtyNum);
        try {
            return (ArrayList<SignatureStamUploadRecordVO>) beansCopy(signatureStamUploadRecords, SignatureStamUploadRecordVO.class);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("转换出错", e);
        }
        return null;
    }

    @Override
    public Integer updateStamRecordByPrimaryKey(SignatureStamUploadRecordVO signatureStamUploadRecordVO) {
        if (Objects.isNull(signatureStamUploadRecordVO)) {
            return 0;
        }
        SignatureStamUploadRecord signatureStamUploadRecord = new SignatureStamUploadRecord();
        beanCopy(signatureStamUploadRecordVO, signatureStamUploadRecord);
        return signatureStamUploadRecordDAO.updateByPrimaryKey(signatureStamUploadRecord);
    }

    /**
     * 获取最大处理数、重试次数
     *
     * @return
     */
    private int[] getHandleNumArr() {
        int[] result = new int[2];
        try {
            SCfgParamVO param = new SCfgParamVO();
            param.setParamKey(PsdConstantSet.MAX_NUM_KEY);
            SCfgParamVO maxNumCfg = sCfgParamService.queryByPk(param);
            if (Objects.isNull(maxNumCfg)) {
                //设置默认值
                result[0] = 50;
            } else {
                result[0] = Integer.parseInt(maxNumCfg.getParamValue());
            }
            param.setParamKey(PsdConstantSet.RETRY_NUM_KEY);
            SCfgParamVO retryNumCfg = sCfgParamService.queryByPk(param);
            if (Objects.isNull(retryNumCfg)) {
                //设置默认值
                result[1] = 3;
            } else {
                result[1] = Integer.parseInt(retryNumCfg.getParamValue());
            }
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        return result;
    }
}